
#include "GateWay.h"
#include <QSharedPointer>
#include "execinfo.h"
#include "signal.h"
#include "csignal"
#include <Encrypt/SM4Encrypt.h>

GateWay::GateWay(QObject *parent)
    : QObject(parent)
{

    qDebug()<<"GateWay runing now---------------------";

    signal(SIGSEGV,System::handlerr);
    signal(SIGABRT,System::handlerr);
    signal(SIGBUS,System::handlerr);
    qDebug()<<"~~~~signal";

    qRegisterMetaType<Package>("Package");
    qRegisterMetaType<PortStruct>("PortStruct");
    qRegisterMetaType<QList<ControlPointStruct> >("QList<ControlPointStruct>");
     qRegisterMetaType<QList<SWKNXDataStruct> >("QList<SWKNXDataStruct>");
    qRegisterMetaType<QSharedPointer<BaseCmd> >("QSharedPointer<BaseCmd>");
    qRegisterMetaType<QSharedPointer<BaseFunc> >("QSharedPointer<BaseFunc>");

    System *system = System::getInstance();
    QString appDirPath = system->appDirPath();
    QString rootPath = system->rootPath();
    system->readVersion();

    Encrypt *encrypt = Encrypt::getInstance();
    encrypt->initRsaKey(rootPath + "/PublicKey.pub");

    qDebug()<<"SM4Encrypt::getInstance()->Init();";
    SM4Encrypt::getInstance()->Init();

    PointIni *pointIni = PointIni::getInstance();
    pointIni->setPath(appDirPath + "/Ini/Point.ini");
    pointIni->parser();

    DeviceIni *DeviceIni = DeviceIni::getInstance();
    DeviceIni->setPath(appDirPath + "/Ini/device.ini");
    DeviceIni->parser();

    MacXml *macXml = MacXml::getInstance();
    macXml->setPath(rootPath + "/MAC.xml");
    macXml->parser();

    BasicXml *basicXml = BasicXml::getInstance();
    basicXml->setPath(appDirPath + "/Xml/Basic.xml");
    basicXml->parser();

    UserListXml *userListXml = UserListXml::getInstance();
    userListXml->setPath(appDirPath + "/Xml/UserList.xml");
    userListXml->parser();

    SceneListXml *sceneListXml = SceneListXml::getInstance();
    sceneListXml->setPath(appDirPath + "/Xml/SceneList.xml");
    sceneListXml->parser();

    RangeListXml *rangeListXml = RangeListXml::getInstance();
    rangeListXml->setPath(appDirPath + "/Xml/RangeResolveList.xml");
    rangeListXml->parser();


    SWKNXListXml *swKNXListXml = SWKNXListXml::getInstance();
    swKNXListXml->setPath(appDirPath + "/Xml/SWKNXList.xml");
    swKNXListXml->parser();

    SavePointXml *savePointXml =SavePointXml::getInstance();
    savePointXml->setPath(appDirPath + "/Xml/SavePoint.xml");
    savePointXml->parser();
    savePointXml->saveTurnStata(false);
    QDateTime systemTime(QDateTime::currentDateTime());
    QString strTime = systemTime.toString("hh:mm:ss");
    savePointXml->setSynchroTime(strTime);

    CustomSceneXml *customSceneXml = CustomSceneXml::getInstance();
    customSceneXml->setPath(appDirPath + "/Xml/CustomSceneList.xml");
    customSceneXml->parser();

    AutomaticXml *automaticXml = AutomaticXml::getInstance();
    automaticXml->setPath(appDirPath + "/Xml/AutomaticList.xml");
    automaticXml->parser();
    automaticXml->setBestTime(0);
    automaticXml->setTimetoGO(0);
    automaticXml->setBestStata(false);
    automaticXml->setTestStata(false);
    LogicControlXml *logicControlXml = LogicControlXml::getInstance();
    logicControlXml->setPath(appDirPath + "/Xml/TempControl.xml");
    logicControlXml->parser();

    IPListXml *ipListXml = IPListXml::getInstance();
    ipListXml->setPath(appDirPath + "/Xml/IPList.xml");
    ipListXml->parser();

    ZigbeeListXml *zigbeeListXml = ZigbeeListXml::getInstance();
    zigbeeListXml->setPath(appDirPath + "/Xml/ZigbeeList.xml");
    zigbeeListXml->parser();

    Zigbee3ListXml *zigbee3ListXml = Zigbee3ListXml::getInstance();
    zigbee3ListXml->setPath(appDirPath + "/Xml/Zigbee3List.xml");
    zigbee3ListXml->parser();

    ModbusListXml *modbusListXml = ModbusListXml::getInstance();
    modbusListXml->setPath(appDirPath + "/Xml/ModbusList.xml");
    modbusListXml->parser();

    OtherEquipmentXml *otherEquipmentXml = OtherEquipmentXml::getInstance();
    otherEquipmentXml->setPath(appDirPath + "/Xml/OtherEquipment.xml");
    otherEquipmentXml->parser();

    ElevatorIPXml *elevatorIPXml =ElevatorIPXml::getInstance();
    elevatorIPXml->setPath(appDirPath + "/Xml/ElevatorIP.xml");
    elevatorIPXml->parser();

    Zigbee3InfraredXml *zigbee3InfraredXml =Zigbee3InfraredXml::getInstance();
    zigbee3InfraredXml->setPath(appDirPath + "/Xml/Zigbee3InfraredXml.xml");
    zigbee3InfraredXml->parser();


    QMap<QString, QMetaObject> portMetaMap;
    portMetaMap.insert(TCPClient::staticMetaObject.className(), TCPClient::staticMetaObject);
    portMetaMap.insert(TCPServer::staticMetaObject.className(), TCPServer::staticMetaObject);
    portMetaMap.insert(UART::staticMetaObject.className(), UART::staticMetaObject);
    portMetaMap.insert(UDP::staticMetaObject.className(), UDP::staticMetaObject);
    portMetaMap.insert(HttpClient::staticMetaObject.className(),HttpClient::staticMetaObject);

    QMap<QString,BaseDevice*> deviceInstanceMap;
    QMap<QString, QMetaObject> deviceMetaMap;
    deviceMetaMap.insert(PointDevice::staticMetaObject.className(), PointDevice::staticMetaObject);
    //deviceMetaMap.insert(PhoneDevice::staticMetaObject.className(), PhoneDevice::staticMetaObject);
    deviceMetaMap.insert(CloudDevice::staticMetaObject.className(), CloudDevice::staticMetaObject);
   // deviceMetaMap.insert(NetPointDevice::staticMetaObject.className(), NetPointDevice::staticMetaObject);
    //deviceMetaMap.insert(ZigbeeDevice::staticMetaObject.className(), ZigbeeDevice::staticMetaObject);
    deviceMetaMap.insert(GowildDevice::staticMetaObject.className(), GowildDevice::staticMetaObject);
    deviceMetaMap.insert(UpperDevice::staticMetaObject.className(), UpperDevice::staticMetaObject);
    deviceMetaMap.insert(ModbusDevice::staticMetaObject.className(), ModbusDevice::staticMetaObject);
    deviceMetaMap.insert(NetPointControlDevice::staticMetaObject.className(), NetPointControlDevice::staticMetaObject);
    //deviceMetaMap.insert(Zigbee3Device::staticMetaObject.className(), Zigbee3Device::staticMetaObject);
    deviceMetaMap.insert(Version2Device::staticMetaObject.className(), Version2Device::staticMetaObject);
    //deviceMetaMap.insert(ZigbeeGWDevice::staticMetaObject.className(), ZigbeeGWDevice::staticMetaObject);
    deviceMetaMap.insert(VigverseDevice::staticMetaObject.className(), VigverseDevice::staticMetaObject);
    deviceMetaMap.insert(SWKNXDevice::staticMetaObject.className(), SWKNXDevice::staticMetaObject);
    deviceMetaMap.insert(SeaWinKNXDevice::staticMetaObject.className(), SeaWinKNXDevice::staticMetaObject);
    deviceMetaMap.insert(WeatherDevice::staticMetaObject.className(), WeatherDevice::staticMetaObject);
    deviceMetaMap.insert(WXTPlatformDevice::staticMetaObject.className(),WXTPlatformDevice::staticMetaObject);
    system->setDeviceMetaMap(deviceMetaMap);
    QList<PortStruct> portParamList = basicXml->portList();
    QMap<QString,BasePort*> portMap;
    foreach (const PortStruct &portParam, portParamList)
    {
        if(!portMetaMap.contains(portParam.type()))
        {
            qDebug()<<"Error:"+portParam.type()+" is an illegal port type!";
            continue;
        }
        QMetaObject meta = portMetaMap.value(portParam.type());
        BasePort *port = qobject_cast<BasePort*>(meta.newInstance());
        if(port == NULL)
        {
            continue;
        }
        portMap.insert(portParam.name(),port);

   #ifdef SSD202
        if(portParam.name() == "RS485")
        {
            qDebug()<<"!!!!!!!!!!!!!!!!!!!!!!=================================PortName==RS485";
            system->enableRS485();
        }
    #endif
        port->setPortParam(portParam);
        port->open();
        QThread *thread = new QThread(this);
        port->moveToThread(thread);
        thread->start();
    }

    LogicController *logicController = new LogicController(this);

    QList<DeviceStruct> deviceParamList = basicXml->deviceList();

    foreach (const DeviceStruct &deviceParam, deviceParamList)
    {
        if(!deviceMetaMap.contains(deviceParam.type()))
        {
            qDebug()<<"Error:"+deviceParam.type()+" is an illegal device type!";
            continue;
        }
        QMetaObject meta = deviceMetaMap.value(deviceParam.type());
        BaseDevice *device = qobject_cast<BaseDevice*>(meta.newInstance());
        if(device == NULL)
            qDebug()<<deviceParam.name() <<"is NULL";
        device->setName(deviceParam.name());
        qDebug()<<"setName="<<device->name();
        QThread *thread = new QThread(this);
        device->moveToThread(thread);
        logicController->registerDevice(device);

        deviceInstanceMap.insert(deviceParam.type(),device);

        connect(SM4Encrypt::getInstance(),SIGNAL(sm4InitComlete()),device,SLOT(onReceiveSM4InitComplete()));

        QStringList bindingPortList = deviceParam.bindingPortList();
        foreach (const QString &bindingPort, bindingPortList)
        {
            BasePort *port = portMap.value(bindingPort,NULL);
            if(port != NULL)
            {
                device->bindingPort(port);
                //qDebug()<<"binding port--"<<device->name();
            }
        }
       // if(device->name() != "CloudDevice")
        thread->start();

    }
     system->setDeviceInstanceMap(deviceInstanceMap);
    Log::removeOutOfDate();



    qDebug()<<"Gateway starts running!";


//    foreach (const PortStruct &portParam, portParamList)
//        {
//            if(!portMetaMap.contains(portParam.type()))
//            {
//                qDebug()<<"Error:"+portParam.type()+" is an illegal port type!";
//                continue;
//            }
//    QMetaObject meta = portMetaMap.value("UART");
//    BasePort *ports = qobject_cast<BasePort*>(meta.newInstance());
//    PortStruct target;
//    target.setType("UART");
//    target.setName("Zigbee");
//    target.setPortName("/dev/ttyS1");
//    target.setMode("Polling");
//    target.setBaudRate("BAUD115200");
//    target.setDataBits("DATA_8");
//    target.setParity("NONE");
//    target.setStopBits("STOP_1");
//    target.setFlowControl("OFF");
//    ports->setPortParam(target);
//    PortStruct targeter=ports->portParam();
//    QByteArray zigbeeversionCmd=zigbee3ListXml->GetZigbeeVersion();
//    ports->write(targeter,zigbeeversionCmd);
//    break;
//    }

    QByteArray zigbeeversionCmd=zigbee3ListXml->GetZigbeeVersion();
    BasePort *port = portMap.value("Zigbee",NULL);
    port->portParam();
    port->write(port->portParam(),zigbeeversionCmd);
}

GateWay::~GateWay()
{

}


